﻿using OkTool.Text;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace OkTool.Util
{
    public class StrUtil : StrPool
    {
        /// <summary>
        /// 切割指定位置之前部分的字符串
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="toIndexExclude">切割到的位置（不包括）</param>
        /// <returns></returns>
        public static string SubPre(string str, int toIndexExclude)
        {
            return Sub(str, 0, toIndexExclude);
        }
        /// <summary>
        /// 查找指定字符串是否包含指定字符串列表中的任意一个字符串
        /// <para>忽略大小写</para>
        /// </summary>
        /// <param name="str">指定字符串</param>
        /// <param name="testStrs">需要检查的字符串数组</param>
        /// <returns></returns>
        public static bool ContainsAnyIgnoreCase(string str, params string[] testStrs)
        {
            return null != GetContainsStrIgnoreCase(str, testStrs);
        }

        /// <summary>
        /// 查找指定字符串是否包含指定字符串列表中的任意一个字符串，如果包含返回找到的第一个字符串
        /// </summary>
        /// <param name="str"></param>
        /// <param name="testStrs"></param>
        /// <returns></returns>
        public static string GetContainsStrIgnoreCase(string str, params string[] testStrs)
        {
            if (IsEmpty(str) || ArrayUtil.IsEmpty(testStrs))
            {
                return null;
            }
            foreach (string testStr in testStrs)
            {
                if (ContainsIgnoreCase(str, testStr))
                {
                    return testStr;
                }
            }
            return null;
        }

        /// <summary>
        /// 查找指定字符串是否包含指定字符串列表中的任意一个字符串
        /// </summary>
        /// <param name="str"></param>
        /// <param name="testStrs"></param>
        /// <returns></returns>
        public static Boolean ContainsAny(string str, params string[] testStrs)
        {
            return null != GetContainsStr(str, testStrs);
        }

        /// <summary>
        /// 查找指定字符串是否包含指定字符串列表中的任意一个字符串，如果包含返回找到的第一个字符串
        /// </summary>
        /// <param name="str"></param>
        /// <param name="testStrs"></param>
        /// <returns></returns>
        public static String GetContainsStr(string str, params string[] testStrs)
        {
            if (IsEmpty(str) || ArrayUtil.IsEmpty(testStrs))
            {
                return null;
            }
            foreach (string checkStr in testStrs)
            {
                if (null != checkStr && str.Contains(checkStr))
                {
                    return checkStr;
                }
            }
            return null;
        }

        /// <summary>
        /// 查找指定字符串是否包含指定字符列表中的任意一个字符
        /// </summary>
        /// <param name="str"></param>
        /// <param name="testChars">需要检查的字符数组</param>
        /// <returns></returns>
        public static bool ContainsAny(string str,params char[] testChars)
        {
            if (false == IsEmpty(str))
            {
                int len = str.Length;
                for (int i = 0; i < len; i++)
                {
                    if (testChars.Contains( str[i]))
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 是否包含特定字符，忽略大小写，如果给定两个参数都为null,返回true
        /// </summary>
        /// <param name="str"></param>
        /// <param name="testStr"></param>
        /// <returns></returns>
        public static bool ContainsIgnoreCase(string str, string testStr)
        {
            if (null == str)
            {
                // 如果被监测字符串和
                return null == testStr;
            }
            return IndexOfIgnoreCase(str, testStr) > -1;
        }


        /// <summary>
        /// 指定范围内查找字符串，忽略大小写
        /// </summary>
        /// <param name="str"></param>
        /// <param name="searchStr"></param>
        /// <returns></returns>
        public static int IndexOfIgnoreCase(string str, string searchStr)
        {
            return str.IndexOf(searchStr, StringComparison.OrdinalIgnoreCase);
        }
        /// <summary>
        /// 创建StringBuilder对象
        /// </summary>
        /// <returns></returns>
        public static StringBuilder Builder()
        {
            return new StringBuilder();
        }

        /// <summary>
        /// 统计指定内容中包含指定字符的数量
        /// </summary>
        /// <param name="content"></param>
        /// <param name="charForSearch">被统计的字符</param>
        /// <returns></returns>
        public static int Count(string content, char charForSearch)
        {
            int count = 0;
            if (string.IsNullOrEmpty(content))
            {
                return 0;
            }
            int contentLength = content.Length;
            for (int i = 0; i < contentLength; i++)
            {
                if (charForSearch == content[i])
                {
                    count++;
                }
            }
            return count;
        }
        /// <summary>
        /// 给定字符串数组全部做去首尾空格
        /// </summary>
        /// <param name="strs"></param>
        public static void Trim(string[] strs)
        {
            if (strs == null)
            {
                return;
            }
            string str;
            for (int i = 0; i < strs.Length; i++)
            {
                str = strs[i];
                if (str != null)
                {
                    strs[i] = str.Trim();
                }
            }
        }

        /// <summary>
        /// 字符串是否为空白,空白的定义如下
        /// <![CDATA[null,"",空格,空白]]>
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsBlank(string str)
        {
            return str == null || str.Length == 0 || string.IsNullOrWhiteSpace(str);
        }

        /// <summary>
        /// 字符串是否为非空白,非空白的定义如下
        /// <list type="number">
        /// <item>不为null</item>
        /// <item>不为空字符串：""</item>
        /// <item>不为空白</item>
        /// </list>
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsNotBlank(string str)
        {
            return !IsBlank(str);
        }
        /// <summary>
        /// 字符串是否为空,空的定义如下
        /// <code>null</code>
        /// <code>""</code>
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsEmpty(string str)
        {
            return str == null || str.Length == 0;
        }

        /// <summary>
        /// 字符串是否为非空白，非空白的定义如下：
        /// <list type="table">
        /// <item>不为 null</item>
        /// <item>不为空字符串：""</item>
        /// </list>
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsNotEmpty(string str)
        {
            return !IsEmpty(str);
        }



        /// <summary>
        /// 去掉指定后缀
        /// </summary>
        /// <param name="str"></param>
        /// <param name="suffix"></param>
        /// <returns></returns>
        public static string RemoveSuffix(string str, string suffix)
        {
            if (IsEmpty(str) || IsEmpty(suffix))
            {
                return str;
            }
            return str.TrimEnd(suffix.ToCharArray());
        }

        /// <summary>
        /// 忽略大小写去掉指定后缀
        /// </summary>
        /// <param name="str"></param>
        /// <param name="suffix"></param>
        /// <returns></returns>
        public static string RemoveSuffixIgnoreCase(string str, string suffix)
        {
            if (IsEmpty(str) || IsEmpty(suffix))
            {
                return str;
            }
            if (str.EndsWith(suffix, StringComparison.OrdinalIgnoreCase))
            {
                return str.Substring(0, str.Length - suffix.Length);
            }
            return str;
        }

        /// <summary>
        /// 忽略大小写去掉指定前缀
        /// </summary>
        /// <param name="str"></param>
        /// <param name="prefix">前缀</param>
        /// <returns></returns>
        public static string RemovePrefixIgnoreCase(string str, string prefix)
        {
            if (IsEmpty(str) || IsEmpty(prefix))
            {
                return str;
            }
            if (str.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
            {
                return str.Substring(prefix.Length);
            }
            return str;
        }

        /// <summary>
        /// 去掉指定前缀
        /// </summary>
        /// <param name="str"></param>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public static string RemovePrefix(string str, string prefix)
        {
            if (IsEmpty(str) || IsEmpty(prefix))
            {
                return str;
            }

            return str.TrimStart(prefix.ToCharArray());
        }

        /// <summary>
        /// 取中间字符串
        /// </summary>
        /// <param name="text"></param>
        /// <param name="leftStirng"></param>
        /// <param name="rightString"></param>
        /// <returns></returns>
        public static string GetMiddle(string text, string leftStirng, string rightString)
        {
            string result;
            if (string.IsNullOrEmpty(text))
            {
                result = "";
            }
            else
            {
                int num = text.IndexOf(leftStirng);
                if (num > -1)
                {
                    num += leftStirng.Length;
                    int num2 = text.IndexOf(rightString, num);
                    if (num2 == -1)
                    {
                        result = "";
                    }
                    else
                    {
                        result = text.Substring(num, num2 - num);
                    }
                }
                else
                {
                    result = "";
                }
            }

            return result;
        }
        /// <summary>
        /// 取左边文本
        /// </summary>
        /// <param name="str"></param>
        /// <param name="left"></param>
        /// <param name="ignoreCase">忽略大小写 则为true 默认区分大小写</param>
        /// <returns></returns>
        public static string GetLeft(string str, string left, bool ignoreCase = false)
        {
            if (string.IsNullOrEmpty(str))
            {
                return "";
            }
            StringComparison comparison = StringComparison.CurrentCulture;

            if (ignoreCase)
            {
                comparison = StringComparison.OrdinalIgnoreCase;
            }

            int index = str.IndexOf(left, comparison);
            if (index == -1) return "";

            return str.Substring(0, index);
        }

        /// <summary>
        /// 取文本右边
        /// </summary>
        /// <param name="str"></param>
        /// <param name="right"></param>
        /// <param name="ignoreCase">忽略大小写 则为true 默认区分大小写</param>
        /// <returns></returns>
        public static string GetRight(string str, string right, bool ignoreCase = false)
        {
            if (string.IsNullOrEmpty(str))
            {
                return "";
            }
            StringComparison comparison = StringComparison.CurrentCulture;

            if (ignoreCase)
            {
                comparison = StringComparison.OrdinalIgnoreCase;
            }

            int index = str.LastIndexOf(right, comparison);
            if (index == -1) return "";

            int index_start = index + right.Length;

            int end_len = str.Length - index_start;
            string temp = str.Substring(index_start, end_len);
            return temp;
        }

        /// <summary>
        /// 替换指定字符串的指定区间内字符为*
        /// </summary>
        /// <param name="str"></param>
        /// <param name="startInclude">开始位置(包含)</param>
        /// <param name="endExclude">结束位置(不包含)</param>
        /// <returns>替换后的字符串</returns>
        public static string Hide(string str, int startInclude, int endExclude)
        {
            return Replace(str, startInclude, endExclude, '*');
        }

        /// <summary>
        /// 替换指定字符串的指定区间内字符为固定字符
        /// </summary>
        /// <param name="str"></param>
        /// <param name="startInclude">开始位置(包含)</param>
        /// <param name="endExclude">结束位置(不包含)</param>
        /// <param name="replacedChar">被替换的字符</param>
        /// <returns></returns>
        public static string Replace(string str, int startInclude, int endExclude, char replacedChar)
        {
            if (string.IsNullOrEmpty(str))
            {
                return str;
            }

            string originalStr = str;
            int strLength = str.Length;

            if (startInclude + 1 > strLength)
            {
                return originalStr;
            }

            if (startInclude > endExclude)
            {
                // 如果起始位置大于结束位置，不替换
                return originalStr;
            }

            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < strLength; i++)
            {
                if (i >= startInclude && i < endExclude)
                {
                    stringBuilder.Append(replacedChar);
                }
                else
                {
                    stringBuilder.Append(str[i]);
                }
            }
            return stringBuilder.ToString();
        }


        /// <summary>
        /// 改进Substring
        /// </summary>
        /// <param name="str"></param>
        /// <param name="fromIndexInclude">开始index</param>
        /// <param name="toIndexExclude">结束的index</param>
        /// <returns></returns>
        public static string Sub(string str, int fromIndexInclude, int toIndexExclude)
        {
            if (string.IsNullOrEmpty(str))
            {
                return str;
            }

            int len = str.Length;

            if (fromIndexInclude < 0)
            {
                fromIndexInclude = len + fromIndexInclude;
                if (fromIndexInclude < 0)
                {
                    fromIndexInclude = 0;
                }
            }
            else if (fromIndexInclude > len)
            {
                fromIndexInclude = len;
            }

            if (toIndexExclude < 0)
            {
                toIndexExclude = len + toIndexExclude;
                if (toIndexExclude < 0)
                {
                    toIndexExclude = len;
                }
            }
            else if (toIndexExclude > len)
            {
                toIndexExclude = len;
            }

            if (toIndexExclude < fromIndexInclude)
            {
                int tmp = fromIndexInclude;
                fromIndexInclude = toIndexExclude;
                toIndexExclude = tmp;
            }

            if (fromIndexInclude == toIndexExclude)
            {
                return string.Empty;
            }

            return str.Substring(fromIndexInclude, toIndexExclude - fromIndexInclude);
        }
    }
}

